How this website was made. PHP, CSS, and Folders.
Disclaimer: This is nothing fancy. I started out with HTML back in the 90's, started using Wordpress in the 00's, and lost interest in the 10's. I am a casual computer user, and didn't keep up with the times. I wanted something I could keep in one folder on my Desktop again. There is a lot of great flat file code out there, but I wanted something I could understand and control. I have tried to keep any code that I borrowed with the authors name. First things first.
Here is what the public_html folder looks like
The main .htaccess file
The .htaccess file redirects pages so they look like they are all in folders, when it is actually a file. Any requests for http://dispelled.ca/j, or http://dispelled.ca/j/ will be shown the page j.php and the same for the other user pages. It also strips any www. from requests.
<IfModule mod_rewrite.c> RewriteCond %{HTTPS} =on RewriteCond %{HTTPS} ^on$ RewriteRule ^(.*)$ http://dispelled.ca/$1 [R=301,L] RewriteRule ^j$ j.php [L] RewriteRule ^j/$ j.php [L] RewriteRule ^cori$ cori.php [L] RewriteRule ^cori/$ cori.php [L] RewriteCond %{HTTP_HOST} ^www\. RewriteCond %{HTTP_HOST} ^www.dispelled.ca$ [NC] RewriteRule ^(.*)$ http://dispelled.ca/$1 [R=301,L] </IfModule>
The main index.php
Basic includes to header.php and footer.php with some RSS feeds of news on the homepage. By the way, whenever I reference a file here, i am using <?php show_source("../../index.php"); ?> Etc. So this is all currently what is running on the webserver. The images shown are from 2014 though lol.
<?php include("header.php"); ?>
<!-- This overrides image display (!important) and keeps iframes off of this page only. -->
<style>
img {display: none !important;}
iframe {display: none;}
</style>
<h1>Dispelled.ca Homepage</h1>
<p>Welcome to our little spot on the Internet. Finally got it back to the basics. This site is made only from <a href="http://dispelled.ca/categories/Code/How%20this%20website%20was%20made.php">a few PHP files and a flat file directory structure</a>.</p>
<p>Things will get broken, and things will get better. Cheers.</p>
<!-- Quick links is back lol! I'll move the CSS later -->
<div style="display: inline-block; background-color:#030303; -webkit-border-top-left-radius: 2ex; -webkit-border-top-right-radius: 2ex; -webkit-border-bottom-left-radius: 2ex; -webkit-border-bottom-right-radius: 2ex;"><div style="padding: 10px;"><p><b>New Links!</b></p>
<p>New in Code: (Oct 20 2024)
<br><a href="https://dispelled.ca/categories/Code/Starting%20with%20Github%20-%20Create%20a%20new%20repository%20on%20the%20command%20line.php">Starting with Github - Create a new repository on the command line</a></p>
<p>New in Code: (Oct 14 2024)
<br><a href="https://dispelled.ca/categories/Code/The%20Branch%20command%20for%20Assembly%20in%20Arm64%20with%20GDB.php">The Branch command for Assembly in Arm64 with GDB</a></p>
<p><a href="https://dispelled.ca/categories/Code/Starting%20to%20learn%20Assembly%20for%20ARMV8%20with%20a%20Khadas%20Vim3%20and%20Ubuntu%2024.04.php">Starting to learn Assembly for ARMV8 with a Khadas Vim3 and Ubuntu 24.04</a></p>
<p><a href="https://dispelled.ca/categories/Code/Debugging%20Assembly%20code%20for%20Arm64%20with%20GDB.php">Debugging Assembly code for Arm64 with GDB</a></p>
<p>New in Cpus: (Oct 14 2024)
<br><a href="https://dispelled.ca/categories/Cpus/Re-installing%20ProtonVPN%20on%20Ubuntu%2024.04%20for%20ARM.php">Re-installing ProtonVPN on Ubuntu 24.04 for ARM</a></p>
</div></div>
<p><b>Old School News Feeds (RSS)</b> <a href="https://dispelled.ca/categories/Code/RSS%20example%20from%20main%20page.php">How?</a></p>
<p><b>Slashdot</b></p>
<?php
$rss = new DOMDocument();
$rss->load('http://rss.slashdot.org/Slashdot/slashdot');
$feed = array();
foreach ($rss->getElementsByTagName('item') as $node) {
$item = array (
'title' => $node->getElementsByTagName('title')->item(0)->nodeValue,
'desc' => $node->getElementsByTagName('description')->item(0)->nodeValue,
'link' => $node->getElementsByTagName('link')->item(0)->nodeValue,
);
array_push($feed, $item);
}
$limit = 5;
for($x=0;$x<$limit;$x++) {
$title = str_replace(' & ', ' & ', $feed[$x]['title']);
$link = $feed[$x]['link'];
$description = $feed[$x]['desc'];
echo '<p><strong><a href="'.$link.'" title="'.$title.'">'.$title.'</a></strong><br />';
echo '<p>'.$description.'</p>';
}
?>
<p><b>Ars Technica</b></p>
<?php
$rss = new DOMDocument();
$rss->load('https://feeds.arstechnica.com/arstechnica/index');
$feed = array();
foreach ($rss->getElementsByTagName('item') as $node) {
$item = array (
'title' => $node->getElementsByTagName('title')->item(0)->nodeValue,
'desc' => $node->getElementsByTagName('description')->item(0)->nodeValue,
'link' => $node->getElementsByTagName('link')->item(0)->nodeValue,
);
array_push($feed, $item);
}
$limit = 20;
for($x=0;$x<$limit;$x++) {
$title = str_replace(' & ', ' & ', $feed[$x]['title']);
$link = $feed[$x]['link'];
$description = $feed[$x]['desc'];
echo '<p><strong><a href="'.$link.'" title="'.$title.'">'.$title.'</a></strong><br />';
echo '<p>'.$description.'</p>';
}
?>
<p><b>Rebel News</b></p>
<?php
$rss = new DOMDocument();
$rss->load('https://www.rebelnews.com/news.rss');
$feed = array();
foreach ($rss->getElementsByTagName('item') as $node) {
$item = array (
'title' => $node->getElementsByTagName('title')->item(0)->nodeValue,
'desc' => $node->getElementsByTagName('description')->item(0)->nodeValue,
'link' => $node->getElementsByTagName('link')->item(0)->nodeValue,
);
array_push($feed, $item);
}
$limit = 20;
for($x=0;$x<$limit;$x++) {
$title = str_replace(' & ', ' & ', $feed[$x]['title']);
$link = $feed[$x]['link'];
$description = $feed[$x]['desc'];
echo '<p><strong><a href="'.$link.'" title="'.$title.'">'.$title.'</a></strong></p>';
}
?>
<p><b>The Gateway Pundit</b></p>
<?php
$rss = new DOMDocument();
$rss->load('https://www.thegatewaypundit.com/rss/');
$feed = array();
foreach ($rss->getElementsByTagName('item') as $node) {
$item = array (
'title' => $node->getElementsByTagName('title')->item(0)->nodeValue,
'desc' => $node->getElementsByTagName('description')->item(0)->nodeValue,
'link' => $node->getElementsByTagName('link')->item(0)->nodeValue,
);
array_push($feed, $item);
}
$limit = 15;
for($x=0;$x<$limit;$x++) {
$title = str_replace(' & ', ' & ', $feed[$x]['title']);
$link = $feed[$x]['link'];
$description = $feed[$x]['desc'];
echo '<p><strong><a href="'.$link.'" title="'.$title.'">'.$title.'</a></strong><br />';
echo '<p>'.$description.'</p>';
}
?>
<p><b>Dissentwatch</b></p>
<?php
$rss = new DOMDocument();
$rss->load('https://dissentwatch.com/?feed=linkfeed');
$feed = array();
foreach ($rss->getElementsByTagName('item') as $node) {
$item = array (
'title' => $node->getElementsByTagName('title')->item(0)->nodeValue,
'desc' => $node->getElementsByTagName('description')->item(0)->nodeValue,
'link' => $node->getElementsByTagName('link')->item(0)->nodeValue,
);
array_push($feed, $item);
}
$limit = 10;
for($x=0;$x<$limit;$x++) {
$title = str_replace(' & ', ' & ', $feed[$x]['title']);
$link = $feed[$x]['link'];
$description = $feed[$x]['desc'];
echo '<p><strong><a href="'.$link.'" title="'.$title.'">'.$title.'</a></strong><br />';
echo '<p>'.$description.'</p>';
}
?>
<p><b>Childrens Health Defense</b></p>
<?php
$rss = new DOMDocument();
$rss->load('https://childrenshealthdefense.org/rss/');
$feed = array();
foreach ($rss->getElementsByTagName('item') as $node) {
$item = array (
'title' => $node->getElementsByTagName('title')->item(0)->nodeValue,
'desc' => $node->getElementsByTagName('description')->item(0)->nodeValue,
'link' => $node->getElementsByTagName('link')->item(0)->nodeValue,
);
array_push($feed, $item);
}
$limit = 20;
for($x=0;$x<$limit;$x++) {
$title = str_replace(' & ', ' & ', $feed[$x]['title']);
$link = $feed[$x]['link'];
$description = $feed[$x]['desc'];
echo '<p><strong><a href="'.$link.'" title="'.$title.'">'.$title.'</a></strong><br />';
echo '<p>'.$description.'</p>';
}
?>
<p><b>Infowars</b></p>
<?php
$rss = new DOMDocument();
$rss->load('https://www.infowars.com/rss.xml');
$feed = array();
foreach ($rss->getElementsByTagName('item') as $node) {
$item = array (
'title' => $node->getElementsByTagName('title')->item(0)->nodeValue,
'desc' => $node->getElementsByTagName('description')->item(0)->nodeValue,
'link' => $node->getElementsByTagName('link')->item(0)->nodeValue,
);
array_push($feed, $item);
}
$limit = 9;
for($x=0;$x<$limit;$x++) {
$title = str_replace(' & ', ' & ', $feed[$x]['title']);
$link = $feed[$x]['link'];
$description = $feed[$x]['desc'];
echo '<p><strong><a href="'.$link.'" title="'.$title.'">'.$title.'</a></strong><br />';
echo '<p>'.$description.'</p>';
}
?>
<?php include("footer.php"); ?>
The header.php
I still need to take this inline CSS out of the header file. It's just easier when you are banging out a new layout. Then it opens the divs. After that is a piece of code I added and modified by Chirp Internet: www.chirp.com.au that takes the contents of my categories folder (in the public_html root), displays each folder name, and links to each folders index.php.
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<title>Dispelled.ca</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,300..800;1,300..800&family=Roboto+Slab:wght@100..900&family=Roboto+Mono:ital,wght@0,400;0,700;1,400;1,700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="/css/normalize.css">
<link rel="stylesheet" href="/css/main.css">
<link rel="stylesheet" href="/css/screen.css">
<link rel="stylesheet" href="/css/light.css">
<link rel="stylesheet" href="/css/dark.css">
<link rel="stylesheet" href="/css/style.css">
<style type="text/css" id="custom-background-css">
body.custom-background {background-image: url('/bg/bg.jpg'); background-repeat: no-repeat; background-position: top left; background-attachment: fixed; background-size: 100%; }
</style>
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
<link rel="manifest" href="/site.webmanifest">
</head>
<body class="custom-background full-width">
<div id="titlediv"><div id="title">
<div style="text-align: right;"><a href="https://github.com/oddlej/" title="@oddlej on Github.com"><img style="padding-top: 63px; display: inline !important" src="https://avatars.githubusercontent.com/u/185309100?v=4&s=48" ></a><a href="/"><img src="/bg/dispelled.png" style="padding-right: 100px; display: inline !important" title="Hocus Pocus Black Magic"></a></div></div></div>
<div class="content">
<div class="flex-menu">
<div id="menu-item" class="menu-item"><a href="/cori/">Cori’s Stuff</a></div><div id="menu-item" class="menu-item"><a href="/j/">J’s stuff</a></div><div id="menu-item" class="menu-item"><a href="https://sellco.ca">Sellco.ca</a></div>
<?PHP
// Original PHP code by Chirp Internet: www.chirp.com.au
// Please acknowledge use of this code by including this header.
function getFileList($dir)
{
// array to hold return value
$retval = array();
// add trailing slash if missing
if(substr($dir, -1) != "/") $dir .= "/";
// open pointer to directory and read list of files
$d = @dir($dir) or die("getFileList: Failed opening directory $dir for reading");
while(false !== ($entry = $d->read())) {
// skip hidden files
if($entry[0] == ".") continue;
if(is_dir("$dir$entry")) {
$retval[] = array(
"name" => "$dir$entry/",
"type" => filetype("$dir$entry"),
"size" => 0,
"lastmod" => filemtime("$dir$entry")
);
} elseif(is_readable("$dir$entry")) {
$retval[] = array(
"name" => "$dir$entry",
"type" => mime_content_type("$dir$entry"),
"size" => filesize("$dir$entry"),
"lastmod" => filemtime("$dir$entry")
);
}
}
$d->close();
return $retval;
}
?>
<?PHP
$dirlist = getFileList("./categories/");
// echo "<ul class=\"sub-menu\">\n";
foreach($dirlist as $file) {
echo "<div class=\"menu-item\">\n";
if(preg_match("/\index.php$/", $file['name'])) continue;
echo "<a href=\"/{$file['name']}\">",basename($file['name']),"</a>\n";
echo "</div>\n";
}
//echo "</ul>\n";
?>
<div id="menu-item" class="menu-item"><a title="Requires Javascript" href="/stocks.php">Stocks</a></div>
</div>
</div>
<!-- Open Divs -->
<div class="content">
<div class="flex-container">
<div id="main" class="wrapper">
The footer.php
<p> </p>
<iframe style="border: 0; width: 100%; height: 120px;" src="https://bandcamp.com/EmbeddedPlayer/album=2730674919/size=large/bgcol=ffffff/linkcol=0687f5/tracklist=false/artwork=small/track=2711575404/transparent=true/" seamless><a href="https://altogethersteveandthemercenaries.bandcamp.com/album/seven-times-refined">Seven Times Refined by Altogether Steve and the Mercenaries</a></iframe>
<p> Check out some other Bands on <a href="https://bandcamp.com/">Bandcamp.com</a>. <a href="https://crazyfingers.bandcamp.com/">Crazy Fingers (Vancouver 1991)</a>, <a href="https://flyingbuttpliers.bandcamp.com/">Flying Butt Pliers</a>, and <a href="https://hammyhamhands.bandcamp.com/">Hammy Ham Hands</a>.</p>
<p><i>Proudly powered by <a href="https://help.gnome.org/users/gedit/stable/">a Text Editor</a>, an <a href="https://filezilla-project.org/">Sftp client</a> and some <a href="https://priv.au/">Internet </a><a href="https://duckduckgo.com/">Searches</a>.</i></p>
<p> 2024 dispelled.ca end of file. </p>
<!-- Close Divs -->
</div><!-- #content -->
</div><!-- #flex-container -->
</div>
</div>
<p> </p>
</body>
</html>
Now to get into the categories folder
So there is a folder called categories, with all of the subjects we want to show in the menu. Any pages in the root of the site will get the categories menu across the top.
Next. Looking into a category
Let's take a look inside the first directory, Code (Back when I wrote this there was a Camp folder). Code is included with the templates.
These folders (categories) use a special header called headercat.php that displays links back to your home pages, and a link back to your categories. It calls on cat.php which displays links to all of the pages in that directory based on the filename. I also added a way to read the first line from each file from a commented date stamp so it would display them based on their post date.
The headercat.php
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<title>Dispelled.ca</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,300..800;1,300..800&family=Roboto+Slab:wght@100..900&family=Roboto+Mono:ital,wght@0,400;0,700;1,400;1,700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="/css/normalize.css">
<link rel="stylesheet" href="/css/main.css">
<link rel="stylesheet" href="/css/screen.css">
<link rel="stylesheet" href="/css/light.css">
<link rel="stylesheet" href="/css/dark.css">
<link rel="stylesheet" href="/css/style.css">
<style type="text/css" id="custom-background-css">
body.custom-background {background-image: url('../../bg/bg.jpg'); background-repeat: no-repeat; background-position: top left; background-attachment: fixed; background-size: 100%; }
</style>
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
<link rel="manifest" href="/site.webmanifest">
</head>
<body class="custom-background full-width">
<div id="titlediv"><div id="title">
<div style="text-align: right;"><a href="https://github.com/oddlej/" title="@oddlej on Github.com"><img style="padding-top: 63px; display: inline !important" src="https://avatars.githubusercontent.com/u/185309100?v=4&s=48" ></a><a href="/"><img src="/bg/dispelled.png" style="padding-right: 100px; display: inline !important" title="Hocus Pocus Black Magic"></a></div></div></div>
<div class="content">
<div class="flex-menu">
<div id="menu-item" class="menu-item"><a href="../../cori/">Cori’s Stuff</a></div><div id="menu-item" class="menu-item"><a href="/j/">J’s stuff</a></div><div id="menu-item" class="menu-item"><a href="../../">Back to Categories >></a></div>
</div>
</div>
<!-- Open Divs -->
<div class="content">
<div class="flex-container">
<div id="main" class="wrapper">
The cat.php
<?PHP
function getPostDate($url) {
$data = file_get_contents($url);
$date = preg_match('/<!--date=(.*?) -->/ims', $data, $matches) ? $matches[1] : null;
return $date;
}
function getTitle($url) {
$data = file_get_contents($url);
//$title = preg_match('/<!--title=(.*?) -->/ims', $data, $matches) ? $matches[1] : null;
$title = preg_match('/<h1[^>]*>(.*?)<\/h1>/ims', $data, $matches) ? $matches[1] : null;
return $title;
}
function sortByTimestamp( $a, $b ) {
if ($a[ 'day' ] == $b[ 'day' ]) {
return 0;
}
return ($a[ 'day' ] > $b[ 'day' ]) ? -1 : 1;
}
// Original PHP code by Chirp Internet: www.chirp.com.au
// Please acknowledge use of this code by including this header.
function getFileListcat($dir)
{
// array to hold return value
$retval = array();
// add trailing slash if missing
if(substr($dir, -1) != "/") $dir .= "/";
// open pointer to directory and read list of files
$d = @dir($dir) or die("getFileList: Failed opening directory $dir for reading");
while(false !== ($entry = $d->read())) {
// skip hidden files
if($entry[0] == ".") continue;
if(is_dir("$dir$entry")) {
$retval[] = array(
"name" => "$dir$entry/",
"type" => filetype("$dir$entry"),
"size" => 0,
"lastmod" => filemtime("$dir$entry")
);
} elseif(is_readable("$dir$entry")) {
$retval[] = array(
"name" => "$dir$entry",
"type" => mime_content_type("$dir$entry"),
"size" => filesize("$dir$entry"),
"lastmod" => filemtime("$dir$entry"),
// added
"tit" => getTitle("$dir$entry"),
"day" => getPostDate("$dir$entry")
);
}
}
$d->close();
usort( $retval, 'sortByTimestamp' );
return $retval;
}
?>
<?PHP
$dirlist = getFileListcat("./");
echo "<ul class=\"cat-menu\">\n";
foreach($dirlist as $file) {
if(preg_match("/\index.php$/", $file['name'])) continue;
if(preg_match("/\error_log$/", $file['name'])) continue;
echo "<li class=\"cat-menu\">\n";
echo "<a href=\"{$file['name']}\">",basename($file['tit']),"</a>\n";
echo "</li>\n";
}
echo "</ul>\n";
?>
The last piece of the puzzle. Adding posts
At this point, you just start adding content. Add folders and add the index.php that looks like this)
<?php include("../../headercat.php"); ?>
<h1>Code</h1>
<p>Assembly, C, Python, Html, Php, Css Etc.</p>
<?php include("../../cat.php"); ?>
<?php include("../../footer.php"); ?>
and then add each post in each category as Name_of_Post.php using the same Name_of_Post for the title and using the <!--date=20141027 --> date stamp, headercat.php and footer.php includes like shown below.
<!--date=20241114 -->
<?php include("../../headercat.php"); ?>
<h1>The Title</h1>
<p> Start Text</p>
<pre>The Code</pre>
</pre>
<p>Some more Text</p><pre>Some more Code
</pre>
<p> </p>
<?php include("../../footer.php"); ?>
That's it! I'll try and get a zip file working one day. (Edit: Dec 2024 - Working on a github repo for this rn ;) Cheers.
Check out some other Bands on Bandcamp.com. Crazy Fingers (Vancouver 1991), Flying Butt Pliers, and Hammy Ham Hands.
Proudly powered by a Text Editor, an Sftp client and some Internet Searches.
2024 dispelled.ca end of file.